package cn.com.css.taxInspection.system.controller;

import cn.com.css.taxInspection.system.service.impl.UserServiceImpl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wf.captcha.utils.CaptchaUtil;
import cn.com.css.taxInspection.common.aop.annotation.LogAnnotation;
import cn.com.css.taxInspection.common.constants.Constants;
import cn.com.css.taxInspection.system.entity.SysLog;
import cn.com.css.taxInspection.system.entity.SysLoginIdentityEntity;
import cn.com.css.taxInspection.system.entity.SysRole;
import cn.com.css.taxInspection.system.entity.SysUser;
import cn.com.css.taxInspection.system.entity.SysUserRole;
import cn.com.css.taxInspection.system.mapper.SysLogMapper;
import cn.com.css.taxInspection.common.exception.code.BaseResponseCode;
import cn.com.css.taxInspection.common.result.DataResult;
import cn.com.css.taxInspection.gt3.entity.DmQxSwrysfEntity;
import cn.com.css.taxInspection.gt3.service.DmGySwjgService;
import cn.com.css.taxInspection.gt3.service.DmQxSwrysfService;
import cn.com.css.taxInspection.system.service.PermissionService;
import cn.com.css.taxInspection.system.service.RedisService;
import cn.com.css.taxInspection.system.service.RoleService;
import cn.com.css.taxInspection.system.service.SysLoginIdentityService;
import cn.com.css.taxInspection.system.service.UserRoleService;
import cn.com.css.taxInspection.system.service.UserService;
import cn.com.css.taxInspection.system.service.impl.HttpSessionService;
import cn.com.css.taxInspection.system.vo.req.UserRoleOperationReqVO;
import cn.com.css.taxInspection.system.vo.res.UserOwnRoleRespVO;
import cn.com.css.taxInspection.util.AesEncryptUtils;
import cn.com.css.taxInspection.util.IPUtils;
import cn.com.css.taxInspection.util.TsBqUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 用户管理
 *
 * @author wenbin
 * @version V1.0
 * @date 2020年3月18日
 */
@RestController
@Api(tags = "组织模块-用户管理")
@RequestMapping("/sys")
@Slf4j
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private HttpSessionService httpSessionService;
    @Resource
    private DmGySwjgService dmGySwjgService;
    @Resource
    private DmQxSwrysfService dmQxSwrysfService;
    @Resource
    private RoleService roleService;
    @Resource
    private SysLoginIdentityService sysLoginIdentityService;
    @Resource
    private PermissionService permissionService;
    @Resource
    private SysLogMapper sysLogMapper;
    @Resource
    private RedisService redisService;
    @Value("${spring.redisToken.key.prefix.userToken}")
    private String userTokenPrefix;

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);


    @PostMapping(value = "/user/login")
    @ApiOperation(value = "用户登录接口")
    public DataResult login(@RequestBody @Valid SysUser vo, HttpServletRequest request) {
        // 解密处理
        try {
            vo.setCaptcha(AesEncryptUtils.decrypt(vo.getCaptcha(), "abcdef0123456789"));
            vo.setUsername(AesEncryptUtils.decrypt(vo.getUsername(), "abcdef0123456789"));
            vo.setPassword(AesEncryptUtils.decrypt(vo.getPassword(), "abcdef0123456789"));
            log.info("查询到的账号：{}", vo.getUsername());
            log.info("查询到的密码：{}", vo.getPassword());
        } catch (Exception e) {
            return DataResult.fail("解密失败，请稍后重试：" + e.getMessage());
        }
        // 判断验证码
        if (!CaptchaUtil.ver(vo.getCaptcha(), request)) {
            // 清除session中的验证码
            CaptchaUtil.clear(request);
            // return DataResult.fail("验证码错误！");
        }
        CaptchaUtil.clear(request);
        return DataResult.success(userService.login(vo, request));
    }

    @PostMapping("/user/register")
    @ApiOperation(value = "用户注册接口")
    public DataResult register(@RequestBody @Valid SysUser vo) {
        userService.register(vo);
        return DataResult.success();
    }

    @GetMapping("/user/unLogin")
    @ApiOperation(value = "引导客户端去登录")
    public DataResult unLogin() {
        return DataResult.getResult(BaseResponseCode.TOKEN_ERROR);
    }

    @PutMapping("/user")
    @ApiOperation(value = "更新用户信息接口")
    @LogAnnotation(title = "用户管理", action = "更新用户信息")
    @RequiresPermissions("sys:user:update")
    public DataResult updateUserInfo(@RequestBody SysUser vo) {
        if (StringUtils.isEmpty(vo.getId())) {
            return DataResult.fail("id不能为空");
        }
        userService.updateUserInfo(vo);
        return DataResult.success();
    }

    @PutMapping("/user/info")
    @ApiOperation(value = "更新用户信息接口")
    @LogAnnotation(title = "用户管理", action = "更新用户信息")
    public DataResult updateUserInfoById(@RequestBody SysUser vo) {
        userService.updateUserInfoMy(vo);
        return DataResult.success();
    }

    @PutMapping("/user/switchidentity")
    @ApiOperation(value = "切换用户身份接口")
    @LogAnnotation(title = "用户管理", action = "切换用户身份接口")
    public DataResult switchUserInfoById(@RequestBody SysUser vo) {
        String currentUserId = httpSessionService.getCurrentUserId();
        // 保存到新表里面
        String swrysfDm1 = vo.getSwrysfDm1();
        String sfswjgDm1 = vo.getSfswjgDm1();
        String rysfmc1 = vo.getRysfmc1();
        if (TsBqUtils.isNotNull(swrysfDm1) && TsBqUtils.isNotNull(sfswjgDm1) && TsBqUtils.isNotNull(rysfmc1)) {
            SysLoginIdentityEntity sysLoginIdentityEntity = new SysLoginIdentityEntity();
            sysLoginIdentityEntity.setSwryDm(currentUserId);
            sysLoginIdentityEntity.setSwrysfDm(swrysfDm1);
            sysLoginIdentityEntity.setSfswjgDm(sfswjgDm1);
            sysLoginIdentityEntity.setRysfmc(rysfmc1);
            sysLoginIdentityEntity.setCreateId(currentUserId);
            sysLoginIdentityEntity.setCreateTime(new Date());
            sysLoginIdentityService.saveOrUpdate(sysLoginIdentityEntity);
        }
        String swrysfDm = vo.getSwrysfDm();
        String sfswjgDm = vo.getSfswjgDm();
        String rysfmc = vo.getRysfmc();
        String token = httpSessionService.getTokenFromHeader();
        List<String> roles = roleService.getRoleNames(swrysfDm);
        List<String> rolesId = roleService.getRoleIds(swrysfDm);
        Set<String> permissions = permissionService.getPermissionsByUserId(swrysfDm);
        JSONObject currentSession = httpSessionService.getCurrentSession();
        currentSession.put(Constants.ROLES_KEY, roles);
        currentSession.put(Constants.ROLES_ID, rolesId);
        currentSession.put(Constants.PERMISSIONS_KEY, permissions);
        currentSession.put(Constants.DEPT_ID, sfswjgDm);
        currentSession.put(Constants.DEPT_NO, sfswjgDm);
        currentSession.put(Constants.IDENTITY_NO, swrysfDm);
        currentSession.put(Constants.IDENTITY_NAME, rysfmc);
        // 更新redis
        redisService.set(userTokenPrefix + token, currentSession.toJSONString());
        List<String> list = new ArrayList<>();
        list.add(swrysfDm);
        list.add(token);
        if (TsBqUtils.isNotNull(rolesId)) {
            list.add(rolesId.toString());
        } else {
            list.add("");
        }
        return DataResult.success(list);
    }

    @GetMapping("/user/{id}")
    @ApiOperation(value = "查询用户详情接口")
    @LogAnnotation(title = "用户管理", action = "查询用户详情")
    @RequiresPermissions("sys:user:detail")
    public DataResult detailInfo(@PathVariable("id") String id) {
        SysUser sysUser = userService.getById(id);
        return DataResult.success(sysUser);
    }

    @GetMapping("/user")
    @ApiOperation(value = "查询用户详情接口")
    @LogAnnotation(title = "用户管理", action = "查询用户详情")
    public DataResult youSelfInfo() {
        String userId = httpSessionService.getCurrentUserId();
        SysUser sysUser = userService.getById(userId);
        return DataResult.success(sysUser);
    }

    @GetMapping("/user/identity")
    @ApiOperation(value = "查询用户身份接口")
    @LogAnnotation(title = "用户管理", action = "查询用户身份详情")
    public DataResult identity() {
        String userId = httpSessionService.getCurrentUserId();
        List<DmQxSwrysfEntity> list = dmQxSwrysfService.getByUserId(userId);
        SysLoginIdentityEntity sysLoginIdentityEntity = sysLoginIdentityService.getById(userId);
        if (TsBqUtils.isNotNull(sysLoginIdentityEntity)) {
            String swrysfDm1 = sysLoginIdentityEntity.getSwrysfDm();
            List<DmQxSwrysfEntity> listHandle = new ArrayList<>();
            for (DmQxSwrysfEntity dmQxSwrysfEntity : list) {
                dmQxSwrysfEntity.setZsfbz("N");
                String swrysfDm2 = dmQxSwrysfEntity.getSwrysfDm();
                if (swrysfDm1.equals(swrysfDm2)) {
                    dmQxSwrysfEntity.setZsfbz("Y");
                }
                listHandle.add(dmQxSwrysfEntity);
            }
            return DataResult.success(listHandle);

        } else {
            return DataResult.success(list);
        }
    }

    @PostMapping("/users")
    @ApiOperation(value = "分页获取用户列表接口")
    @RequiresPermissions("sys:user:list")
    @LogAnnotation(title = "用户管理", action = "分页获取用户列表")
    public DataResult pageInfo(@RequestBody SysUser vo) {
        IPage<DmQxSwrysfEntity> iPage = userService.pageInfo(vo);
        return DataResult.success(iPage);
    }

    @PostMapping("/user")
    @ApiOperation(value = "新增用户接口")
    @RequiresPermissions("sys:user:add")
    @LogAnnotation(title = "用户管理", action = "新增用户")
    public DataResult addUser(@RequestBody @Valid SysUser vo) {
        userService.addUser(vo);
        return DataResult.success();
    }

    @GetMapping("/user/logout")
    @ApiOperation(value = "退出接口")
    @LogAnnotation(title = "用户管理", action = "退出")
    public DataResult logout() {
        httpSessionService.abortUserByToken();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return DataResult.success();
    }

    @PutMapping("/user/pwd")
    @ApiOperation(value = "修改密码接口")
    @LogAnnotation(title = "用户管理", action = "更新密码")
    public DataResult updatePwd(@RequestBody SysUser vo) {
        if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) {
            return DataResult.fail("旧密码与新密码不能为空");
        }
        String userId = httpSessionService.getCurrentUserId();
        vo.setId(userId);
        userService.updatePwd(vo);
        return DataResult.success();
    }

    @DeleteMapping("/user")
    @ApiOperation(value = "删除用户接口")
    @LogAnnotation(title = "用户管理", action = "删除用户")
    @RequiresPermissions("sys:user:deleted")
    public DataResult deletedUser(@RequestBody @ApiParam(value = "用户id集合") List<String> userIds) {
        // 删除用户， 删除redis的绑定的角色跟权限
        httpSessionService.abortUserByUserIds(userIds);
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(SysUser::getId, userIds);
        userService.remove(queryWrapper);
        return DataResult.success();
    }


    @PostMapping("/userinitPassword")
    @ApiOperation(value = "用户密码初始化接口")
    @LogAnnotation(title = "用户管理", action = "用户密码初始化")
    public DataResult userinitPassword(@RequestBody @ApiParam(value = "用户id集合") String userId) {
        // 删除用户， 删除redis的绑定的角色跟权限
        SysUser sysUser = userService.getById(userId);
        sysUser.setSalt("1b91bb478d5e413b8736");
        sysUser.setPassword("8adc58c58060fac2c95c81f14c2529b7");
        sysUser.setStatus(1);
        sysUser.setUpdateTime(new Date());
        sysUser.setUpdateId(httpSessionService.getCurrentUserId());
        userService.updateById(sysUser);
        return DataResult.success();
    }

    @GetMapping("/user/roles/{userId}")
    @ApiOperation(value = "赋予角色-获取所有角色接口")
    @LogAnnotation(title = "用户管理", action = "赋予角色-获取所有角色接口")
    public DataResult getUserOwnRole(@PathVariable("userId") String userId) {
        DataResult result = DataResult.success();
        UserOwnRoleRespVO userOwnRole = userService.getUserOwnRole(userId);
        List<SysRole> allRole = userOwnRole.getAllRole();
        List<SysRole> allRole1 = new ArrayList<>();
        for (SysRole sysRole : allRole) {
            String dataScope = String.valueOf(sysRole.getDataScope());
            if (dataScope.equals(Constants.LEVEL_SHENGJU) || dataScope.equals(Constants.LEVEL_SHIJU)
                    || dataScope.equals(Constants.LEVEL_XIANQUJU)) {
                allRole1.add(sysRole);
            }
        }
        userOwnRole.setAllRole(allRole1);
        result.setData(userOwnRole);
        return result;
    }

    @PutMapping("/user/roles/{userId}")
    @ApiOperation(value = "赋予角色-用户赋予角色接口")
    @LogAnnotation(title = "用户管理", action = "赋予角色-用户赋予角色接口")
    @RequiresPermissions("sys:user:update:role")
    public DataResult setUserOwnRole(@PathVariable("userId") String userId, @RequestBody List<String> roleIds) {
        LambdaQueryWrapper<SysUserRole> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysUserRole::getUserId, userId);
        userRoleService.remove(queryWrapper);
        if (null != roleIds && !roleIds.isEmpty()) {
            UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO();
            reqVO.setUserId(userId);
            reqVO.setRoleIds(roleIds);
            userRoleService.addUserRoleInfo(reqVO);
        }
        httpSessionService.refreshUerId(userId);
        return DataResult.success();
    }
}
